package app

import (
	"app_log_server/app/core"
	"fmt"
	"os"
	"strings"

	"gorm.io/driver/postgres"
	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
)

var Config core.ConfigModel
var dbInstance *gorm.DB

func Init(homePath string) error {
	config_file := homePath + "/config/config_default.yml"
	config_override_file := homePath + "/config/config.yml"
	err := Config.ParseConfig(config_file)
	if err != nil {
		return err
	}
	err = Config.ParseConfig(config_override_file)
	if err != nil {
		return err
	}
	return nil

}

func GetDB() *gorm.DB {
	if dbInstance != nil {
		return dbInstance
	}

	if Config.Database == "postgres" {
		dsn_config := fmt.Sprintf("user=%s dbname=%s password=%s host=%s port=%s sslmode=disable TimeZone=%s",
			Config.Postgres.User,
			Config.Postgres.DBName,
			Config.Postgres.Password,
			Config.Postgres.Host,
			Config.Postgres.Port,
			Config.Postgres.TimeZone)
		db, err := gorm.Open(postgres.New(postgres.Config{
			DSN:                  dsn_config,
			PreferSimpleProtocol: true, // disables implicit prepared statement usage
		}), &gorm.Config{})

		if err != nil {
			panic("failed to connect database")
		}
		dbInstance = db
		initConns(db)
		return db
	} else if Config.Database == "sqlite" {
		db, err := gorm.Open(sqlite.Open(Config.Sqlite.Path), &gorm.Config{})
		if err != nil {
			panic("failed to connect database")
		}
		dbInstance = db
		initConns(db)
		return db
	} else {
		panic("database type not supported")
	}

}

func initConns(db *gorm.DB) {
	sqlDB, err := db.DB()
	if err != nil {
		panic(err)
	}
	sqlDB.SetMaxIdleConns(10)
	sqlDB.SetMaxOpenConns(100)
}

func InitDatabase(sql_file string, db *gorm.DB) error {
	sqlContent, err := os.ReadFile(sql_file)
	if err != nil {
		return err
	}
	statements := strings.Split(string(sqlContent), ";")
	for _, statement := range statements {
		if err := db.Exec(statement).Error; err != nil {
			return err
		}
	}

	fmt.Println("SQL file executed successfully")
	return nil
}
